package com.teacher.game.framework.util;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

/**
 * 得分管理器 - 负责游戏得分计算、存储和统计
 * 实现多维度评分系统和数据持久化
 */
public class ScoreManager {
    private static final String PREFS_NAME = "EllioGamePrefs";
    private static final String HIGH_SCORE_KEY = "HighScore";
    private static final String TOTAL_GAMES_KEY = "TotalGames";
    private static final String TOTAL_BLOCKS_PASSED_KEY = "TotalBlocksPassed";
    private static final String TOTAL_PLAYTIME_KEY = "TotalPlayTime";
    
    // 得分规则常量
    private static final int POINTS_PER_SECOND = 10;    // 每秒基础分
    private static final int POINTS_PER_BLOCK = 50;     // 每个障碍物得分
    private static final int JUMP_BONUS = 10;           // 跳跃奖励分
    private static final int DUCK_BONUS = 10;           // 下蹲奖励分
    private static final int PERFECT_DODGE_BONUS = 25;  // 完美躲避奖励
    
    // 当前游戏数据
    private int currentScore;           // 当前游戏得分
    private int highScore;              // 历史最高分
    private int totalGames;             // 总游戏次数
    private float gameTime;             // 当前游戏时长
    private int blocksPassedCount;      // 当前游戏越过的障碍物数量
    private int jumpCount;              // 当前游戏跳跃次数
    private int duckCount;              // 当前游戏下蹲次数
    private int comboCount;             // 连击计数
    
    // 统计数据
    private int totalBlocksPassed;      // 历史总越过障碍物数
    private float totalPlayTime;        // 历史总游戏时间
    
    private SharedPreferences prefs;
    private boolean isNewRecord = false;
    
    /**
     * 构造函数
     * @param context Android上下文
     */
    public ScoreManager(Context context) {
        prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        loadGameData();
        reset();
    }
    
    /**
     * 重置当前游戏得分和统计
     */
    public void reset() {
        currentScore = 0;
        gameTime = 0;
        blocksPassedCount = 0;
        jumpCount = 0;
        duckCount = 0;
        comboCount = 0;
        isNewRecord = false;
        
        Log.d("ScoreManager", "游戏数据已重置");
    }
    
    /**
     * 更新游戏时间并计算基础得分（支持双倍得分效果）
     * @param deltaTime 时间增量（秒）
     */
    public void updateTime(float deltaTime) {
        gameTime += deltaTime;
        
        // 更新双倍得分效果
        updateDoubleScoreEffect(deltaTime);
        
        // 基于时间的得分 (每秒10分)
        int baseTimeScore = (int)(gameTime * POINTS_PER_SECOND);
        int timeScore = doubleScoreActive ? baseTimeScore * 2 : baseTimeScore;
        
        // 重新计算总得分（考虑双倍效果）
        int baseScore = timeScore + (blocksPassedCount * POINTS_PER_BLOCK) + 
                       (jumpCount * JUMP_BONUS) + (duckCount * DUCK_BONUS);
        
        currentScore = baseScore;
    }
    
    /**
     * 玩家成功越过障碍物
     */
    public void passedBlock() {
        blocksPassedCount++;
        currentScore += POINTS_PER_BLOCK;
        
        // 检查连续躲避奖励
        if (blocksPassedCount % 10 == 0) {
            currentScore += PERFECT_DODGE_BONUS;
            Log.d("ScoreManager", "连续躲避10个障碍物！奖励" + PERFECT_DODGE_BONUS + "分");
        }
        
        Log.d("ScoreManager", "越过障碍物! 总数: " + blocksPassedCount + ", 当前得分: " + currentScore);
    }
    
    /**
     * 玩家执行跳跃动作
     */
    public void onJump() {
        jumpCount++;
        currentScore += JUMP_BONUS;
    }
    
    /**
     * 玩家执行下蹲动作
     */
    public void onDuck() {
        duckCount++;
        currentScore += DUCK_BONUS;
    }
    
    /**
     * 游戏结束，保存得分和统计数据
     */
    public void gameOver() {
        totalGames++;
        totalBlocksPassed += blocksPassedCount;
        totalPlayTime += gameTime;
        
        // 检查是否创造新记录
        if (currentScore > highScore) {
            highScore = currentScore;
            isNewRecord = true;
            Log.d("ScoreManager", "新纪录! 最高分: " + highScore);
        }
        
        // 保存数据到本地存储
        saveGameData();
        
        Log.d("ScoreManager", String.format(
            "游戏结束 - 得分:%d, 时长:%.1f秒, 跳跃:%d次, 下蹲:%d次, 障碍物:%d个",
            currentScore, gameTime, jumpCount, duckCount, blocksPassedCount));
    }
    
    /**
     * 从SharedPreferences加载游戏数据
     */
    private void loadGameData() {
        highScore = prefs.getInt(HIGH_SCORE_KEY, 0);
        totalGames = prefs.getInt(TOTAL_GAMES_KEY, 0);
        totalBlocksPassed = prefs.getInt(TOTAL_BLOCKS_PASSED_KEY, 0);
        totalPlayTime = prefs.getFloat(TOTAL_PLAYTIME_KEY, 0.0f);
        
        Log.d("ScoreManager", String.format(
            "游戏数据已加载 - 最高分:%d, 总游戏:%d次, 总障碍物:%d个, 总时长:%.1f秒",
            highScore, totalGames, totalBlocksPassed, totalPlayTime));
    }
    
    /**
     * 保存游戏数据到SharedPreferences
     */
    private void saveGameData() {
        SharedPreferences.Editor editor = prefs.edit();
        editor.putInt(HIGH_SCORE_KEY, highScore);
        editor.putInt(TOTAL_GAMES_KEY, totalGames);
        editor.putInt(TOTAL_BLOCKS_PASSED_KEY, totalBlocksPassed);
        editor.putFloat(TOTAL_PLAYTIME_KEY, totalPlayTime);
        editor.apply();
        
        Log.d("ScoreManager", "游戏数据已保存到本地存储");
    }
    
    /**
     * 清除所有游戏数据 (用于重置功能)
     */
    public void clearAllData() {
        SharedPreferences.Editor editor = prefs.edit();
        editor.clear();
        editor.apply();
        
        highScore = 0;
        totalGames = 0;
        totalBlocksPassed = 0;
        totalPlayTime = 0.0f;
        
        Log.d("ScoreManager", "所有游戏数据已清除");
    }
    
    // === 格式化显示方法 ===
    
    /**
     * 获取格式化的当前得分显示
     * @return 格式化后的得分字符串
     */
    public String getFormattedCurrentScore() {
        return String.format("得分: %06d", currentScore);
    }
    
    /**
     * 获取格式化的最高分显示
     * @return 格式化后的最高分字符串
     */
    public String getFormattedHighScore() {
        return String.format("最高分: %06d", highScore);
    }
    
    /**
     * 获取游戏时间显示
     * @return 格式化的时间字符串 (MM:SS)
     */
    public String getFormattedGameTime() {
        int minutes = (int) gameTime / 60;
        int seconds = (int) gameTime % 60;
        return String.format("时间: %02d:%02d", minutes, seconds);
    }
    
    /**
     * 获取游戏统计信息
     * @return 统计信息字符串
     */
    public String getGameStats() {
        return String.format("游戏 %d 次 | 障碍物 %d 个 | 最高分 %d", 
                           totalGames, totalBlocksPassed, highScore);
    }
    
    /**
     * 获取当前游戏详细统计
     * @return 详细统计字符串
     */
    public String getCurrentGameStats() {
        return String.format("跳跃 %d 次 | 下蹲 %d 次 | 越过 %d 个障碍物", 
                           jumpCount, duckCount, blocksPassedCount);
    }
    
    /**
     * 计算游戏等级（基于总得分）
     * @return 玩家等级
     */
    public int getPlayerLevel() {
        return Math.max(1, highScore / 1000); // 每1000分升一级
    }
    
    /**
     * 获取平均每次游戏得分
     * @return 平均得分
     */
    public int getAverageScore() {
        if (totalGames == 0) return 0;
        // 这里需要保存历史总得分才能计算真实平均值
        // 简化实现：基于最高分估算
        return highScore / Math.max(1, totalGames / 3);
    }
    
    // === Getter方法 ===
    
    public int getCurrentScore() { return currentScore; }
    public int getHighScore() { return highScore; }
    public int getTotalGames() { return totalGames; }
    public float getGameTime() { return gameTime; }
    public int getBlocksPassedCount() { return blocksPassedCount; }
    public int getJumpCount() { return jumpCount; }
    public int getDuckCount() { return duckCount; }
    public int getComboCount() { return comboCount; }
    public int getTotalBlocksPassed() { return totalBlocksPassed; }
    public float getTotalPlayTime() { return totalPlayTime; }
    public boolean isNewRecord() { return isNewRecord; }
    
    // === 调试和测试方法 ===
    
    /**
     * 手动添加分数 (仅用于调试)
     * @param points 要添加的分数
     */
    public void addScore(int points) {
        currentScore += points;
        Log.d("ScoreManager", "手动添加分数: " + points + ", 当前得分: " + currentScore);
    }
    
    /**
     * 获取得分规则说明
     * @return 规则说明字符串
     */
    public String getScoringRules() {
        return String.format(
            "计分规则:\n" +
            "• 生存时间: %d分/秒\n" +
            "• 越过障碍物: %d分/个\n" +
            "• 跳跃动作: %d分/次\n" +
            "• 下蹲动作: %d分/次\n" +
            "• 连续躲避10个: %d分奖励",
            POINTS_PER_SECOND, POINTS_PER_BLOCK, JUMP_BONUS, DUCK_BONUS, PERFECT_DODGE_BONUS
        );
    }
    
    // ========== 道具系统支持 ==========
    
    // 道具效果状态
    private boolean doubleScoreActive = false;
    private float doubleScoreDuration = 0;
    private int powerUpsCollected = 0;  // 当前游戏收集的道具数
    
    /**
     * 添加奖励分数（道具系统使用）
     * @param bonus 奖励分数
     */
    public void addBonus(int bonus) {
        int finalBonus = doubleScoreActive ? bonus * 2 : bonus;
        currentScore += finalBonus;
        Log.d("ScoreManager", "道具奖励: " + bonus + " (实际: " + finalBonus + "), 当前得分: " + currentScore);
    }
    
    /**
     * 激活双倍得分效果
     * @param duration 持续时间（秒）
     */
    public void activateDoubleScore(float duration) {
        doubleScoreActive = true;
        doubleScoreDuration = duration;
        Log.d("ScoreManager", "双倍得分激活: " + duration + "秒");
    }
    
    /**
     * 更新双倍得分效果（在update方法中调用）
     * @param delta 时间增量
     */
    private void updateDoubleScoreEffect(float delta) {
        if (doubleScoreActive) {
            doubleScoreDuration -= delta;
            if (doubleScoreDuration <= 0) {
                doubleScoreActive = false;
                doubleScoreDuration = 0;
                Log.d("ScoreManager", "双倍得分效果结束");
            }
        }
    }
    
    /**
     * 记录道具收集
     */
    public void collectPowerUp() {
        powerUpsCollected++;
        Log.d("ScoreManager", "收集道具，当前游戏总计: " + powerUpsCollected);
    }
    
    /**
     * 检查双倍得分是否激活
     */
    public boolean isDoubleScoreActive() {
        return doubleScoreActive;
    }
    
    /**
     * 获取双倍得分剩余时间
     */
    public float getDoubleScoreDuration() {
        return doubleScoreDuration;
    }
    
    /**
     * 获取当前游戏收集的道具数
     */
    public int getPowerUpsCollected() {
        return powerUpsCollected;
    }
}